package com.heima.comment.service.impl;

import com.heima.comment.feign.UserFeign;
import com.heima.comment.service.CommentService;
import com.heima.common.aliyun.GreeTextScan;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vo.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import com.sun.xml.bind.v2.model.core.TypeRef;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.xml.stream.events.Comment;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Log4j2
public class CommentServiceImpl implements CommentService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    UserFeign userFeign;
    @Autowired
    GreeTextScan greeTextScan;
    @Resource(name = "likesLock")
    RLock rLock;
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //检查参数
        if (dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
//        //判断是否登录
//        ApUser user = AppThreadLocalUtils.getUser();
//        if (user == null) {
//            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
//        }
        ApUser user = new ApUser();
        user.setId(4);
        user.setName("测试用户");
        //点赞操作
        rLock.lock();
        ApComment apComment;
       try {
            apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
           if (apComment != null && dto.getOperation() == 0) {
               //更新评论的点赞数量
               apComment.setLikes(apComment.getLikes() + 1);
               mongoTemplate.save(apComment);
               //保存app评论信息点赞
               ApCommentLike apCommentLike = new ApCommentLike();
               apCommentLike.setAuthorId(user.getId());
               apCommentLike.setCommentId(apComment.getId());
               apCommentLike.setOperation(dto.getOperation());
               mongoTemplate.save(apCommentLike);
           } else if (apComment != null && dto.getOperation() == 1) {
               //取消点赞
               //更新评论的点赞数量
               apComment.setLikes(apComment.getLikes() < 0 ? 0 : apComment.getLikes() - 1);
               mongoTemplate.save(apComment);
               //更新 app评论信息点赞
               mongoTemplate.remove(Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(apComment.getId())), ApCommentLike.class);
           }
       }finally {
           rLock.unlock();
       }

        //数据返回
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes", apComment.getLikes());
        return ResponseResult.okResult(resultMap);
    }

    @Override
    public ResponseResult saveCommen(CommentSaveDto dto) {
        //检查参数
        if (dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getContent() != null && dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE, "评论字数不能超过140字符");
        }
        //判断是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //安全过滤
        try {
            Map map = greeTextScan.greeTextScan(dto.getContent());
            String suggestion =(String) map.get("suggestion");
            if("block".equals(suggestion)){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"评论中有违规内容");
            }
        }catch (Exception e){
            e.getStackTrace();
            log.error("阿里云文本检测出现错误 {}",e.getCause());
        }
        //保存评论
        ApUser apUser = userFeign.findUserById(user.getId().longValue());
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN, "登录信息出错");
        }
        ApComment apComment = new ApComment();
        apComment.setAuthorId(apUser.getId());
        apComment.setAuthorName(apUser.getName());
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setType((short) 0);
        apComment.setFlag((short) 0);
        mongoTemplate.insert(apComment);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //检查参数
        if (dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        int size = 20;
        //按照文章id过滤，设置分页和排序
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("createdTime").lt(dto.getMinDate()));
        query.limit(size).with(Sort.by(Sort.Direction.DESC, "createdTime"));
        //获取评论列表
        List<ApComment> list = mongoTemplate.find(query, ApComment.class);
        //数据封装返回
        //用户未登录 加载数据
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.okResult(list);
        }
        //用户已登录 加载数据 判断当前用户点赞了那些评论
        if (list != null && list.size() > 0) {
            //利用stream流查询评论id列表
            List<String> commentIdList = list.stream().map(ApComment::getId).collect(Collectors.toList());
            //根据评论id列表及当前登录用户id 去mongo点赞集合查询
            Query likesQuery = Query.query(Criteria.where("commentId").in(commentIdList).and("authorId").is(user.getId()));
            //得到当前评论中 所有当前用户点赞过的信息
            List<ApCommentLike> apCommentLikes = mongoTemplate.find(likesQuery, ApCommentLike.class);
            //点过赞的评论id
            Set<String> AllCommentLikes = apCommentLikes.stream().map(ApCommentLike::getCommentId).collect(Collectors.toSet());
            //将每一条评论转成vo对象 如果是我评论过的需要将operation字段设置为0
            ArrayList<ApCommentVo> resultList = new ArrayList<>();
            if (list != null && apCommentLikes != null) {
                list.stream().forEach(x -> {
                    ApCommentVo apCommentVo = new ApCommentVo();
                    BeanUtils.copyProperties(x, apCommentVo);
                    for (ApCommentLike apCommentLike : apCommentLikes) {
                        if (x.getId().equals(apCommentLike.getCommentId())) {
                            apCommentVo.setOperation((short) 0);
                            break;
                        }
                    }
                    resultList.add(apCommentVo);
                });
                return ResponseResult.okResult(resultList);
            }

        }
        return ResponseResult.okResult(list);
    }
}